package tcp

import (
	"encoding/json"
	"fmt"
	"io"
	"iot-protocol-oob/codec/decoder"
	"iot-protocol-oob/protocol"
	"math/rand"
	"net"
	"time"
)

type ClientInfo struct {
	clientConn *net.TCPConn
	clientIp   string
}

type ServerTCP struct {
	port          uint16
	connectClient map[string]*ClientInfo
}

func NewServerTCP(port uint16) *ServerTCP {
	svr := &ServerTCP{
		port:          port,
		connectClient: make(map[string]*ClientInfo),
	}
	return svr
}

func (server *ServerTCP) Open() error {

	//ip, _ := utils.GetLocalIP()
	ip := "127.0.0.1"
	address := fmt.Sprintf("%s%s%d", ip, ":", server.port)
	addr, _ := net.ResolveTCPAddr("tcp", address)
	tcp, err := net.ListenTCP("tcp", addr)
	if err != nil {
		fmt.Println(err)
		return err
	}
	defer func(tcp *net.TCPListener) {
		err := tcp.Close()
		if err != nil {

		}
	}(tcp)
	rand.Seed(time.Now().Unix())
	startMsg := fmt.Sprintf("%s%d", "ServiceTCP启动成功 port ", server.port)
	println(startMsg)
	for {
		accept, err := tcp.AcceptTCP()
		if err != nil {
			fmt.Println(err)
			return err
		}
		client := ClientInfo{clientConn: accept, clientIp: accept.RemoteAddr().String()}
		server.connectClient[accept.RemoteAddr().String()] = &client
		go handlerConn(accept)
	}
}

func handlerConn(c net.Conn) {

	srcIp := c.RemoteAddr().String()
	fmt.Printf("handlerConn %s\n", srcIp)
	defer func(c net.Conn) {
		err := c.Close()
		if err != nil {
			fmt.Println(err.Error())
		}
	}(c)
	buf := make([]byte, 1)
	Cache := make([]byte, 0)
	for {
		n, err := c.Read(buf[:])
		if err == io.EOF {
			break
		}
		if err != nil {
			fmt.Println("read from client failed, err:", err)
			break
		}
		pkg, c := decoder.ModbusRTUDecoder{Buf: buf[:n], Cache: Cache}.Decode()
		Cache = c
		if pkg == nil || len(pkg) == 0 {
			continue
		}
		frame, _ := protocol.NewRTUFrame(pkg)
		marshal, _ := json.Marshal(frame)
		fmt.Println("接收消息 [" + string(marshal) + "]")
		//content := hex.EncodeToString(pkg)
		//fmt.Println(content)
		//msg := Message{ProtocolType: "tcp", SrcId: "", SrcIp: srcIp, Content: pkg, ContentHexStr: content}
		//marshal, _ := json.Marshal(msg)
		//fmt.Println("接收消息 [" + string(marshal) + "]")
		//msg = Message{ProtocolType: "tcp", SrcId: "", SrcIp: "", Content: pkg, ContentHexStr: content}
		//broadcastMessage(msg, sr)
	}
}

// 单独发送
func signalMessage(message protocol.Message, conn *net.TCPConn) {

	_, err := conn.Write(message.Content)
	var state string
	if err != nil {
		state = "fail"
	} else {
		state = "success"
	}
	marshal, _ := json.Marshal(message)
	fmt.Println("signal发送消息 state " + state + " message [" + string(marshal) + "]")
}

// 广播发送
func broadcastMessage(message protocol.Message, sr *ServerTCP) {

	// 遍历所有客户端并发送消息
	for _, client := range sr.connectClient {
		_, err := client.clientConn.Write(message.Content)
		var state string
		if err != nil {
			state = "fail"
		} else {
			state = "success"
		}
		marshal, _ := json.Marshal(message)
		fmt.Println("broadcast发送消息 state " + state + " message [" + string(marshal) + "]")
	}
}
